package com.modernyuanshiren;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class CombinationSupplier implements Supplier<String> {
	private int numOfDefineDigits;
	private int flag = 0;
	private final int m;
	private Function<Integer, String> mapper = String::valueOf;

	List<Integer> com = new ArrayList<>();

	/**
	 * if pick 4 digits out of 0~9,then numOfDefineDigits is 10(as 0~9 are 10
	 * digits),and numOfResultDigits is 4.
	 * 
	 * @param numOfDefineDigits
	 * @param numOfResultDigits
	 */
	public CombinationSupplier(int numOfDefineDigits, int numOfResultDigits) {
		this.numOfDefineDigits = numOfDefineDigits;
		m = numOfResultDigits;
		com.add(1);
		IntStream.range(0, numOfDefineDigits).forEach(t -> com.add(0));
	}

	/**
	 * default display : 0からの数字。
	 * 
	 * @param mapper
	 *            0からの数字->表示用文字列
	 */
	public void setDisplayMapper(Function<Integer, String> mapper) {
		this.mapper = mapper;
	}

	@Override
	public String get() {
		while (true) {
			if (com.get(flag) > numOfDefineDigits - m + flag + 1) {
				if (flag == 0) {
					throw new RuntimeException("完了");
				}
				nextLevel();
			} else {
				String result = null;
				if (flag == m - 1) {
					result = com.stream().limit(m).map(d -> d - 1).map(mapper)
							.collect(Collectors.joining());
				}
				doAfter();
				if (result != null) {
					return result;
				}
			}
		}

	}

	private void nextLevel() {
		flag--;
		com.set(flag, com.get(flag) + 1);
	}

	private void doAfter() {
		com.set(flag + 1, com.get(flag) + 1);
		flag++;
		if (flag == m) {
			nextLevel();
		}
	}


}
